package com.tsingteng.cosfun.ui.costar;

import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;

import com.qiniu.pili.droid.shortvideo.PLMediaFile;
import com.qiniu.pili.droid.shortvideo.PLShortVideoTrimmer;
import com.qiniu.pili.droid.shortvideo.PLVideoFrame;
import com.qiniu.pili.droid.shortvideo.PLVideoSaveListener;
import com.tsingteng.cosfun.R;
import com.tsingteng.cosfun.base.BaseVideoActivity;
import com.tsingteng.cosfun.common.Config;
import com.tsingteng.cosfun.common.Navigate;
import com.tsingteng.cosfun.utils.LogUtils;
import com.tsingteng.cosfun.utils.StringUtils;
import com.tsingteng.cosfun.utils.ToastUtils;
import com.tsingteng.cosfun.utils.VideoUtils;
import com.tsingteng.cosfun.widget.CompletedView;
import com.tsingteng.cosfun.widget.FrameSelectorView;
import com.tsingteng.cosfun.widget.PressImageView;
import com.tsingteng.cosfun.widget.dialog.ContentDialog;
import com.tsingteng.cosfun.widget.dialog.CustomProgressDialog;

/**
 * 描述: 剪辑视屏
 * 创建人: 肖利
 * 时间: 2018/8/2
 * qq: (872179966)
 */

public class VideoDivideActivity extends BaseVideoActivity implements View.OnClickListener{

    private LinearLayout mFrameListView;
    private PressImageView mHandlerLeft;
    private PressImageView mHandlerRight;
    private PLShortVideoTrimmer mShortVideoTrimmer;
    private PLMediaFile mMediaFile;
    private String videoPath;

    private VideoView mPreview;

    private long mSelectedBeginMs;
    private long mSelectedEndMs;

    private static final int SLICE_COUNT = 8;
    private int mVideoFrameCount;
    private int mSlicesTotalLength;
    private long mDurationMs;
    private LinearLayout mLlProgress;
    private CompletedView mCcProgress;
    private TextView mTvProgress;
    private FrameSelectorView mCurSelectorView;

    private TextView mTvSave;
    private TextView mTvCancle;
    private Handler mHandler = new Handler();



    @Override
    public void initView() {
        mPreview = findViewById(R.id.preview);
        mFrameListView =  findViewById(R.id.video_frame_list);
        mTvSave =  findViewById(R.id.tv_save);
        mTvCancle =  findViewById(R.id.tv_cancle);
        mCurSelectorView = findViewById(R.id.fs_select);
//        mHandlerLeft = findViewById(R.id.handler_left1);
//        mHandlerRight = findViewById(R.id.handler_right1);
//        mHandlerRight = findViewById(R.id.handler_right);
        mLlProgress = findViewById(R.id.ll_progress);
        mCcProgress = findViewById(R.id.ccp_progress);
        mTvProgress = findViewById(R.id.tv_progress);
        mShortVideoTrimmer = new PLShortVideoTrimmer(this, videoPath, VideoUtils.TRIM_FILE_PATH);
        mMediaFile = new PLMediaFile(videoPath);
        mTvSave.setOnClickListener(this);
        mTvSave.setOnClickListener(this);
        mCcProgress.setMaxProgress(100);
        mCcProgress.setProgress(0);
        mTvProgress.setText("0%");
        mSelectedEndMs = mDurationMs = mMediaFile.getDurationMs();
        LogUtils.d("video duration: " + mDurationMs);

        mVideoFrameCount = mMediaFile.getVideoFrameCount(false);
        LogUtils.d("video frame count: " + mVideoFrameCount);

        mPreview.setVideoPath(videoPath);
        mPreview.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {
                play();
            }
        });

        mCurSelectorView.setOnEventActionListener(new FrameSelectorView.OnEventActionListener() {
            @Override
            public void actionUpClick() {
                calculateRange();
            }
        });



        initVideoFrameList();

    }


    @Override
    protected void onResume() {
        super.onResume();
        play();
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopTrackPlayProgress();
        if (mPreview!= null) {
            mPreview.pause();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mShortVideoTrimmer != null) {
            mShortVideoTrimmer.destroy();
        }
        if (mMediaFile != null) {
            mMediaFile.release();
        }

        if (mPreview !=null) {
            mPreview.stopPlayback();
        }
    }

    /**
     * 播放视屏
     */
    private void play() {
        if (mPreview != null) {
            mPreview.seekTo((int) mSelectedBeginMs);
            mPreview.start();
            startTrackPlayProgress();
        }
    }

    private void startTrackPlayProgress() {
        stopTrackPlayProgress();
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (mPreview.getCurrentPosition() >= mSelectedEndMs) {
                    mPreview.seekTo((int) mSelectedBeginMs);
                }
                mHandler.postDelayed(this, 100);
            }
        }, 100);
    }
    private void stopTrackPlayProgress() {
        mHandler.removeCallbacksAndMessages(null);
    }


    /**
     * 初始化下面预览界面
     */
    private void initVideoFrameList() {

        mFrameListView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mFrameListView.getViewTreeObserver().removeOnGlobalLayoutListener(this);

                final int sliceEdge = mFrameListView.getWidth() / SLICE_COUNT;
                mSlicesTotalLength = sliceEdge * SLICE_COUNT;
                LogUtils.d("slice edge: " + sliceEdge);
                final float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());

                class MyTask extends AsyncTask<Void, PLVideoFrame, Void> {

                    @Override
                    protected Void doInBackground(Void... voids) {
                        for (int i = 0; i < SLICE_COUNT; ++i) {
                            PLVideoFrame frame = mMediaFile.getVideoFrameByTime((long) ((1.0f * i / SLICE_COUNT) * mDurationMs), true, sliceEdge, sliceEdge);
                            publishProgress(frame);
                        }
                        return null;
                    }

                    @Override
                    protected void onProgressUpdate(PLVideoFrame... values) {
                        super.onProgressUpdate(values);
                        PLVideoFrame frame = values[0];
                        if (frame != null) {
                            View root = LayoutInflater.from(VideoDivideActivity.this).inflate(R.layout.frame_item, null);

                            int rotation = frame.getRotation();
                            ImageView thumbnail =  root.findViewById(R.id.thumbnail);
                            thumbnail.setImageBitmap(frame.toBitmap());
                            thumbnail.setRotation(rotation);
                            FrameLayout.LayoutParams thumbnailLP = (FrameLayout.LayoutParams) thumbnail.getLayoutParams();
                            if (rotation == 90 || rotation == 270) {
                                thumbnailLP.leftMargin = thumbnailLP.rightMargin = (int) px;
                            } else {
                                thumbnailLP.topMargin = thumbnailLP.bottomMargin = (int) px;
                            }
                            thumbnail.setLayoutParams(thumbnailLP);

                            LinearLayout.LayoutParams rootLP = new LinearLayout.LayoutParams(sliceEdge, sliceEdge);
                            mFrameListView.addView(root, rootLP);
                        }
                    }
                }
                new MyTask().execute();
            }
        });


    }

    private void calculateRange() {
        float beginPercent = 1.0f * (mCurSelectorView.getBodyLeft() - mFrameListView.getX()) / mSlicesTotalLength;
        float endPercent = 1.0f * (mCurSelectorView.getBodyRight() - mFrameListView.getX()) / mSlicesTotalLength;
        beginPercent = clamp(beginPercent);
        endPercent = clamp(endPercent);

        LogUtils.d("begin percent: " + beginPercent + " end percent: " + endPercent);

        mSelectedBeginMs = (long) (beginPercent * mDurationMs);
        mSelectedEndMs = (long) (endPercent * mDurationMs);
        mCurSelectorView.setTvTime("已选"+StringUtils.div((mSelectedEndMs-mSelectedBeginMs),1000,1)+"秒");
        LogUtils.d("new range: " + mSelectedBeginMs + "-" + mSelectedEndMs);
        play();
        if (StringUtils.div((mSelectedEndMs-mSelectedBeginMs),1000,1)>60) {
            mTvSave.setTextColor(getResources().getColor(R.color.white_alpha_40));
            mTvSave.setEnabled(false);
        }else {
            mTvSave.setTextColor(getResources().getColor(R.color.white));
            mTvSave.setEnabled(true);
        }

        LogUtils.d("begin mSelectedEndMs: " + mSelectedEndMs + " end mSelectedBeginMs: " + mSelectedBeginMs);
    }


    private float clamp(float origin) {
        if (origin < 0) {
            return 0;
        }
        if (origin > 1) {
            return 1;
        }
        return origin;
    }


    /**
     * 得到传递的数据
     *
     * @param intent
     */
    @Override
    public void getIntentData(Intent intent) {
        videoPath = intent.getStringExtra("videoPath");
    }

    @Override
    public int getLayoutId() {
        return R.layout.activity_video_divide;
    }

    public void onDone() {

        LogUtils.d("trim to file path: " + VideoUtils.TRIM_FILE_PATH + " range: " + mSelectedBeginMs + " - " + mSelectedEndMs);
        mLlProgress.setVisibility(View.VISIBLE);

        mShortVideoTrimmer.trim(mSelectedBeginMs, mSelectedEndMs,  PLShortVideoTrimmer.TRIM_MODE.ACCURATE, new PLVideoSaveListener() {
            @Override
            public void onSaveVideoSuccess(String path) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mLlProgress.setVisibility(View.GONE);
                        Intent intent = new Intent(VideoDivideActivity.this,PreViewActivity.class);
                        intent.putExtra(VideoUtils.VIDEO_PATH,path);
                        startActivity(intent);
                        finish();
                    }
                });
            }

            @Override
            public void onSaveVideoFailed(final int errorCode) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mLlProgress.setVisibility(View.GONE);
                        ToastUtils.showToast(errorCode);
                    }
                });
            }

            @Override
            public void onSaveVideoCanceled() {
                mLlProgress.setVisibility(View.GONE);;
            }

            @Override
            public void onProgressUpdate(final float percentage) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mCcProgress.setProgress((int) (100 * percentage));
                        mTvProgress.setText((int) (100 * percentage)+"%");
                    }
                });
            }
        });
    }


    @Override
    public void onBackPressed() {
        Intent intent = new Intent(VideoDivideActivity.this,PreViewActivity.class);
        intent.putExtra(VideoUtils.VIDEO_PATH,videoPath);
        startActivity(intent);
        finish();
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_save:
                onDone();
                break;
            case R.id.tv_cancle:
                break;
        }
    }
}
